package _Pan3D.particle
{
	import _Pan3D.base.Camera3D;
	import _Pan3D.base.Focus3D;
	import _Pan3D.particle.interfaces.IParticle;
	
	import _me.Scene_data;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display3D.Context3D;
	import flash.display3D.Context3DProgramType;
	import flash.display3D.Context3DTextureFormat;
	import flash.display3D.Context3DVertexBufferFormat;
	import flash.display3D.IndexBuffer3D;
	import flash.display3D.VertexBuffer3D;
	import flash.display3D.textures.Texture;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;

	public class UVParticle extends BaseParticle implements IParticle
	{
		private var verterAry:Vector.<Number>;
		//private var verterAry2:Vector.<Number>;
		private var indexAry:Vector.<uint>;
		
		//private var _context3D:Context3D;
		private var verterBuffer:VertexBuffer3D;
		//private var verterBuffer2:VertexBuffer3D;
		private var indexBuffer:IndexBuffer3D;
		private var textureBuffer:Texture;
		
		private var _currentFrame:int;
		private var _allFrame:int;
		private var _wNum:int;
		private var _hNum:int;
		//private var _callFun:Function;
		
		
		private var modelMatix:Matrix3D;
		
		protected var modelMatrix:Matrix3D;
		//protected var posMatrix:Matrix3D;
		
		//protected var _x:Number = 0;
		//protected var _y:Number = 0;
		//protected var _z:Number = 0;
		
		public function UVParticle(context:Context3D)
		{
			super(context);
			modelMatrix = new Matrix3D;
			posMatrix = new Matrix3D;
			init();
		}
		public var num:int = 1;
		public function init():void{
			verterAry = new Vector.<Number>;
			indexAry = new Vector.<uint>;
		}
		
		public function gotoAndPlay(frame:int):void{
			this._currentFrame = frame;
		}
		
		public function setWHnum(wNum:int,hNum:int):void{
			this._wNum = wNum;
			this._hNum = hNum;
			this._allFrame = wNum*hNum;
			
			verterAry.push(-1,1,0,0,0);
			verterAry.push(1,1,0,1/wNum,0);
			verterAry.push(1,-1,0,1/wNum,1/hNum);
			verterAry.push(-1,-1,0,0,1/hNum);
			
			indexAry.push(0,1,2,0,2,3);
			
			upLoadToGpu();
			
		}
		
		
		
		private function upLoadToGpu():void{
			verterBuffer = _context3D.createVertexBuffer(4*num,5);
			verterBuffer.uploadFromVector(verterAry,0,verterAry.length/5);
			
			indexBuffer = _context3D.createIndexBuffer(indexAry.length);
			indexBuffer.uploadFromVector(indexAry,0,indexAry.length);
			
			
			if(textureBuffer == null){
				var bitmapdata:BitmapData = Bitmap(new cls()).bitmapData;
				textureBuffer = this._context3D.createTexture(bitmapdata.width, bitmapdata.height, Context3DTextureFormat.BGRA, true);
				textureBuffer.uploadFromBitmapData(bitmapdata);
			}
			
		}
		[Embed(source="../_File/uvpatricle/guagnhuan.png")]
		private var cls:Class;
		/*public function uploadTexture(bitmapdata:BitmapData):void{
			textureBuffer = this._context3D.createTexture(bitmapdata.width, bitmapdata.height, Context3DTextureFormat.BGRA, true);
			textureBuffer.uploadFromBitmapData(bitmapdata);
		}
		
		private function addTexture(texture : Texture,obj:Object) : void {
			this.textureBuffer = texture;
		}*/
		public function update(ts:Number = 0):void{
			_context3D.setProgram(_program);
			if(t>=speed){
				_currentFrame++;
				if(_currentFrame == _allFrame){
					_currentFrame = 0;
					//this.dispatchEvent(new Event(Event.COMPLETE));
					playEnd();
				}
				t=0;
			}
			t += ts;
			
			if(textureBuffer){
				setVc();
				setVa();
				resetVa();
			}
		}
		
		private function playEnd():void{
			this.end = true;
			_callFun(this);
		}
		
		override public function reset():void{
			super.reset();
			_currentFrame = 0;
			t = 0;
		}
		
		public function updateMatrix():void{
			modelMatrix.identity();
			modelMatrix.prepend(Scene_data.cam3D.cameraMatrix);
			modelMatrix.prepend(posMatrix);
		}
		private function setVa():void{
			_context3D.setVertexBufferAt(0,verterBuffer,0,Context3DVertexBufferFormat.FLOAT_3);
			_context3D.setVertexBufferAt(1,verterBuffer,3,Context3DVertexBufferFormat.FLOAT_2);
			
			_context3D.setTextureAt(0,textureBuffer);
			_context3D.drawTriangles(indexBuffer,0,-1);
		}
		private function resetVa():void{
			_context3D.setVertexBufferAt(0,null);
			_context3D.setVertexBufferAt(1,null);
			_context3D.setVertexBufferAt(2,null);
			_context3D.setTextureAt(0,null);
		}
		private var t:int = 0;
		
		private var tempM:Matrix3D=new Matrix3D;
		public var speed:int = 5;
		private function setVc():void{
			this.updateMatrix();
			
			var _Cam:Camera3D=Scene_data.cam3D;
			var _focus_3d:Focus3D=Scene_data.focus3D;
			
			_Cam.cameraMatrix.identity();
			_Cam.cameraMatrix.prependScale(1, _Cam.fovw / _Cam.fovh, 1);
			_Cam.cameraMatrix.prependTranslation(0, 0, -_Cam.distance);
			_Cam.cameraMatrix.prependTranslation(-_focus_3d.x, -_focus_3d.y, -_focus_3d.z);
			
			modelMatrix.identity();
			modelMatrix.prepend(_Cam.cameraMatrix);
			modelMatrix.prepend(posMatrix);
			
			tempM.identity();
			tempM.prependRotation(_Cam.angle_x  , Vector3D.X_AXIS);
			tempM.prependRotation(_Cam.angle_y  , Vector3D.Y_AXIS);
			
			_context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 4, modelMatrix, true);
			_context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 8, tempM, true);
			
			var xx:Number = int(_currentFrame%_wNum)/_wNum;
			var yy:Number = int(_currentFrame/_wNum)/_hNum;
			trace(xx)
			_context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 12, Vector.<Number>([xx,yy, -0.001, 0]));
			
			_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([-0.001, 0, 0, 1]));
			
		}
		/*
		public function get x():Number
		{
			return _x;
		}
		
		public function set x(value:Number):void
		{
			_x = value;
			updataPos();
		}
		
		public function get y():Number
		{
			return _y;
		}
		
		public function set y(value:Number):void
		{
			_y = value;
			updataPos();
		}
		
		public function get z():Number
		{
			return _z;
		}
		
		public function set z(value:Number):void
		{
			_z = value;
			updataPos();
		}
		
		public function set scale(value:Number):void{
			
		}
		
		private var _scale:Number = 1;
		public function updataPos():void{
			posMatrix.identity();
			//posMatrix.prependRotation(-90, new Vector3D(1, 0, 0));
			posMatrix.prependTranslation(this._x, this._y, this._z);
			posMatrix.prependScale(this._scale,this._scale,this._scale);
			//posMatrix.prependRotation(_rotationY , Vector3D.Y_AXIS);
		} 
*/
	/*	public function set callFun(value:Function):void
		{
			_callFun = value;
		}
*/
	}
}